from django import template
from ytbase.model.comment import *
from ytbase.helper import *

register = template.Library()

class CommentListNode(template.Node):
    def __init__(self, obj, context_var_name, page=None, num_per_page=None, descending=False, extra_kwargs=None):
        self.obj = obj
        self.context_var_name = context_var_name
        self.page = page
        self.num_per_page = num_per_page
        self.descending = descending
        self.extra_kwargs = extra_kwargs or {}

    def render(self, context):
        try:
            obj = template.resolve_variable(self.obj, context)
        except template.VariableDoesNotExist:
            return ''

        if self.page:
            try:
                page = template.resolve_variable(self.page, context)
                num_per_page = template.resolve_variable(self.num_per_page, context)
            except template.VariableDoesNotExist:
                return ''
        else:
            page = 1
            num_per_page = 10            
        
        filters = []
        filters.append(lambda q: q.filter('ref =', obj))
        if self.descending:
            filters.append(lambda q: q.order('-date'))
        else:
            filters.append(lambda q: q.order('date'))

        query = build_query(cls=YTComment, filters=filters)
        paginator = SimplePaginator(query, num_per_page, page)
        comments, page = paginator.get_page_objects()

        for comment in comments:
            comment.auth = get_auth((YTComment, comment))

        context[self.context_var_name] = comments
        context['page_info'] = page
        return ''

class DoGetCommentList:
    """
    Gets comments for the given params and populates the template context with a
    special comment_package variable, whose name is defined by the ``as``
    clause.

    Syntax::

        {% get_comment_list for [obj] as [varname] paginator [num] [num_per_page] (descending) %}

    Example usage::

        {% get_comment_list for post as comment_list paginator 2 10 %}
    """
    def __call__(self, parser, token):
        tokens = token.contents.split()
        if not len(tokens) in (5, 6, 8, 9):
            raise template.TemplateSyntaxError, "%r tag requires 5 to 8 arguments" % tokens[0]
        if tokens[1] != 'for':
            raise template.TemplateSyntaxError, "Second argument in %r tag must be 'for'" % tokens[0]
        obj = tokens[2]
        if tokens[3] != 'as':
            raise template.TemplateSyntaxError, "Third argument in %r must be 'as'" % tokens[0]

        if len(tokens) in (8, 9):
            if tokens[5] != 'paginator':
                raise template.TemplateSyntaxError, "Fifth argument in %r must be 'paginator' if given" % tokens[0]
            page = tokens[6]
            num_per_page = tokens[7]
        else:
            page = None
            num_per_page = None
        
        if len(tokens) == 6 or len(tokens) == 9:
            if tokens[-1] != 'descending':
                raise template.TemplateSyntaxError, "Final argument in %r must be 'reversed' if given" % tokens[0]
            descending = True
        else:
            descending = False
        return CommentListNode(obj, tokens[4], page, num_per_page, descending)

register.tag('get_comment_list', DoGetCommentList())
